home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 January / macformat-020.iso / Shareware City / Developers / apps.to.go / DTS.Lib / AppleTalk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-04  |  9.3 KB  |  336 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** Program:         DTS.Lib
  5. ** File:         AppleTalk.c
  6. ** Written by:   Pete Helme and Jim Luther
  7. ** Modified by:  Eric Soldan
  8. **
  9. ** Copyright © 1989-1991 Apple Computer, Inc.
  10. ** All rights reserved.
  11. */
  12.  
  13. /* You may incorporate this sample code into your applications without
  14. ** restriction, though the sample code has been provided "AS IS" and the
  15. ** responsibility for its operation is 100% yours.  However, what you are
  16. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  17. ** after having made changes. If you're going to re-distribute the source,
  18. ** we require that you make it clear in the source that the code was
  19. ** descended from Apple Sample Code, but that you've made changes. */
  20.  
  21.  
  22.  
  23. /*****************************************************************************/
  24.  
  25.  
  26.  
  27. #include "DTS.Lib2.h"
  28. #include "DTS.Lib.protos.h"
  29.  
  30. #ifndef __ERRORS__
  31. #include <Errors.h>
  32. #endif
  33.  
  34. #ifndef __LISTCONTROL__
  35. #include "ListControl.h"
  36. #endif
  37.  
  38. #ifndef __OSUTILS__
  39. #include <OSUtils.h>
  40. #endif
  41.  
  42. #ifndef __RESOURCES__
  43. #include <Resources.h>
  44. #endif
  45.  
  46.  
  47.  
  48. #define        kATPTimeOutVal            3            /* re-try ATP SendRequest every 3 seconds */
  49. #define        kATPRetryCount            5            /* for five times */
  50. #define        kZonesSize                578            /* size of buffer for zone names */
  51. #define        kGetMyZoneCall            0x07000000    /* GetMyZone indicator */
  52. #define        kGetZoneListCall        0x08000000    /* GetZoneList indicator */
  53. #define        kZIPSocket                6            /* the Zone Information Protocol socket */
  54. #define        kMoreZones                0xFF000000     /* mask to see if more zones to come */
  55. #define        kZoneCount                0x0000FFFF     /* mask to count zones in buffer */
  56.  
  57. #define        kTupleSize    104
  58. #define        kMaxTuples    1
  59.  
  60.  
  61.  
  62. /*****************************************************************************/
  63.  
  64.  
  65.  
  66. #pragma segment myPPC
  67. OSErr    ATInit(void)
  68. {
  69.     return(noErr);
  70. }
  71.  
  72.  
  73.  
  74. /*****************************************************************************/
  75.  
  76.  
  77.  
  78. /* Create the list of zones on the network.  Find a bridge to talk to, if one is
  79. ** present, then ask it for zone names.  Add the names to the passed-in list. */
  80.  
  81. #pragma segment myPPC
  82. OSErr    DoBuildZoneList(ListHandle listHndl)
  83. {
  84.     ATPParamBlock    atppb;
  85.     char            zones[kZonesSize], *zptr, data[255];
  86.     OSErr            err;
  87.  
  88.     BDSElement    dBDS;                /* the BDS for GetZoneList call */
  89.     short        index, count, i;
  90.     short        ignore;
  91.     short        nodeNetAddress, bridgeNode;
  92.  
  93.     dBDS.buffSize = kZonesSize;                                    /* set up BDS */
  94.     dBDS.buffPtr = zones;
  95.  
  96.     atppb.ATPatpFlags = 0;
  97.  
  98.     /* Get network address of node & node ID of bridge (if any). */
  99.  
  100.     err = GetNodeAddress(&ignore, &nodeNetAddress);
  101.     if (err) return(err);
  102.  
  103.     if (!(bridgeNode = GetBridgeAddress())) return(noErr);
  104.         /* We have added all zero zones to the ist, so we are done. */
  105.  
  106.     atppb.ATPaddrBlock.aNet = nodeNetAddress;
  107.     atppb.ATPaddrBlock.aNode = bridgeNode;            /* Get node of bridge. */
  108.     atppb.ATPaddrBlock.aSocket = kZIPSocket;        /* The socket we want. */
  109.     atppb.ATPreqLength = 0;
  110.     atppb.ATPreqPointer = nil;
  111.     atppb.ATPbdsPointer = (Ptr) &dBDS;
  112.     atppb.ATPnumOfBuffs = 1;
  113.     atppb.ATPtimeOutVal = kATPTimeOutVal;
  114.     atppb.ATPretryCount = kATPRetryCount;
  115.  
  116.     index = 1;
  117.     count = 0;
  118.  
  119.     do {
  120.         atppb.ATPuserData = kGetZoneListCall + index;    /* Indicate GetZoneList request. */
  121.         err = PSendRequest(&atppb, false);                /* Send sync request. */
  122.         if (err) return(err);
  123.  
  124.         count += dBDS.userBytes & kZoneCount;            /* find out how many returned */
  125.         zptr = zones;                                    /* put current pointer at start */
  126.         do {                                            /* get each zone */
  127.             for (i = zptr[0]; i; --i)
  128.                 data[i - 1] = zptr[i];
  129.             CLInsert(listHndl, data, zptr[0], -1, 0);
  130.             zptr += (*zptr + 1 );                        /* bump up current pointer*/
  131.             ++index;                                    /* increment which zone */
  132.         } while(index <= count);
  133.  
  134.     } while ((dBDS.userBytes & kMoreZones) == 0);        /*     keep going until none left */
  135.  
  136.     return(noErr);
  137. }
  138.  
  139.  
  140.  
  141. /*****************************************************************************/
  142.  
  143.  
  144.  
  145. /* Select our zone in the zone list. */
  146.  
  147. #pragma segment myPPC
  148. OSErr    OldStyleGetMyZone(StringPtr str);
  149. OSErr    HiliteUserZone(ListHandle listHndl)
  150. {
  151.     Str32            zone;
  152.     short            zoneLen, i;
  153.     Point            cell;
  154.     OSErr            err;
  155.  
  156.     if (!(err = OldStyleGetMyZone(zone))) {
  157.         for (zoneLen = zone[i = 0]; i < zoneLen; ++i) zone[i] = zone[i + 1];
  158.         cell.h = cell.v = 0;
  159.         if (LSearch(zone, zoneLen, nil, &cell, listHndl)) {
  160.             LSetSelect(true, cell, listHndl);
  161.             LAutoScroll(listHndl);
  162.         }
  163.     }
  164.     return(err);
  165. }
  166.  
  167.  
  168.  
  169. /*****************************************************************************/
  170.  
  171.  
  172.  
  173. #pragma segment myPPC
  174. OSErr    OldStyleGetMyZone(StringPtr str)
  175. {
  176.     ATPParamBlock    atppb;
  177.     OSErr            err;
  178.  
  179.     BDSElement    dBDS;                /* the BDS for GetZoneList call */
  180.     short        ignore;
  181.     short        nodeNetAddress, bridgeNode;
  182.  
  183.     dBDS.buffSize = sizeof(Str32);
  184.     dBDS.buffPtr  = (Ptr)str;
  185.  
  186.     atppb.ATPatpFlags = 0;
  187.  
  188.     /* Get network address of node & node ID of bridge (if any). */
  189.  
  190.     err = GetNodeAddress(&ignore, &nodeNetAddress);
  191.     if (err) return(err);
  192.  
  193.     if (!(bridgeNode = GetBridgeAddress())) return(noErr);
  194.         /* We have added all zero zones to the ist, so we are done. */
  195.  
  196.     atppb.ATPaddrBlock.aNet    = nodeNetAddress;
  197.     atppb.ATPaddrBlock.aNode   = bridgeNode;            /* Get node of bridge. */
  198.     atppb.ATPaddrBlock.aSocket = kZIPSocket;            /* The socket we want. */
  199.     atppb.ATPreqLength  = 0;
  200.     atppb.ATPreqPointer = nil;
  201.     atppb.ATPbdsPointer = (Ptr) &dBDS;
  202.     atppb.ATPnumOfBuffs = 1;
  203.     atppb.ATPtimeOutVal = kATPTimeOutVal;
  204.     atppb.ATPretryCount = kATPRetryCount;
  205.  
  206.     atppb.ATPuserData = kGetMyZoneCall;                /* Indicate GetMyZone request. */
  207.     return(PSendRequest(&atppb, false));            /* Send sync request. */
  208. }
  209.  
  210.  
  211.  
  212.  
  213. /*****************************************************************************/
  214.  
  215.  
  216.  
  217. /* This routine finds the socket used by the PPC Toolbox (it's the one with
  218. ** type 'PPCToolBox') and gives it a NBP alias (it registers a new NBP name
  219. ** on that socket) with the type passed in newNBPType.  The NameTableEntry
  220. ** record passed to this routine must be allocated globally (or must be a
  221. ** locked block on the heap until RemoveNBPAlias is called).  The variable
  222. ** newEntity is filled in with the new entity name and is returned to the
  223. ** function's caller so it can be passed to the RemoveNBPAlias function
  224. ** (below).  You'll get an error if any call fails, if an entity of type
  225. ** 'PPCToolBox' is not found (usually because either Program Linking isn't
  226. ** enabled or AppleTalk is disabled), or if RegisterName fails because >100
  227. ** copies of your application are running on the one machine. */
  228.  
  229. #pragma segment myPPC
  230. OSErr    AddPPCNBPAlias(NamesTableEntry *theNTE, Str32 newNBPType, EntityName *newEntity)
  231. {
  232.     OSErr            err;
  233.     MPPParamBlock    pb;
  234.     char            keepSelfFlag;
  235.     short            keepResFile, origLen, num, len;
  236.  
  237.     EntityName        myEntityName;
  238.  
  239.     AddrBlock        myAddrBlock;
  240.     char            myRetBuff[kTupleSize];
  241.     Handle            machineNameHndl;
  242.     Str32            machineName;
  243.  
  244.     pb.SETSELF.newSelfFlag = 1;
  245.     err = PSetSelfSend(&pb, false);                        /* Turn on self-send. */
  246.     if (err) return(err);
  247.  
  248.     keepSelfFlag = pb.SETSELF.oldSelfFlag;                /* Keep old self-send flag. */
  249.  
  250.     keepResFile = CurResFile();
  251.     UseResFile(0);
  252.     machineNameHndl = GetResource('STR ', -16413);        /* Get machine name. */
  253.     UseResFile(keepResFile);
  254.  
  255.     if (!machineNameHndl) {
  256.         pb.SETSELF.newSelfFlag = keepSelfFlag;
  257.         PSetSelfSend(&pb, false);
  258.         return(ResError());
  259.     }
  260.  
  261.     pcpy(machineName, (StringPtr)*machineNameHndl);        /* Keep a copy of the machine name.   */
  262.     ReleaseResource(machineNameHndl);                    /* Release the machine name resource. */
  263.  
  264.     NBPSetEntity((Ptr)&myEntityName, (Ptr)machineName, (Ptr)"\pPPCToolBox", (Ptr)"\p*");
  265.  
  266.     pb.NBPinterval    = 1;                    /* We want to build the entity name using */
  267.     pb.NBPcount       = 1;                    /* the machine name and 'PPCToolBox'.     */
  268.     pb.NBPentityPtr   = (Ptr)&myEntityName;
  269.     pb.NBPretBuffPtr  = myRetBuff;
  270.     pb.NBPretBuffSize = (kTupleSize * kMaxTuples);
  271.     pb.NBPmaxToGet    = kMaxTuples;
  272.  
  273.     if (!(err = PLookupName(&pb, false))) {        /* If lookup was okay... */
  274.         if (pb.NBPnumGotten) {                    /* If entity was found... */
  275.                                     /* ...we found the socket used by the PPC Toolbox. */
  276.                                     /* This means that there is a socket, due to program */
  277.                                     /* linking being turned on. */
  278.  
  279.             NBPExtract(myRetBuff, pb.NBPnumGotten, 1, &myEntityName, &myAddrBlock);
  280.                 /* Break the tuple into component parts. */
  281.  
  282.             for (origLen = machineName[num = 0]; num < 100;) {
  283.  
  284.                 pb.NBPinterval   = 7;
  285.                 pb.NBPcount      = 5;
  286.                 pb.NBPentityPtr  = (Ptr)theNTE;
  287.                 pb.NBPverifyFlag = 1;
  288.  
  289.                 NBPSetNTE((Ptr)theNTE, (Ptr)machineName, (Ptr)newNBPType, (Ptr)"\p*", myAddrBlock.aSocket);
  290.                 NBPSetEntity((Ptr)newEntity, (Ptr)machineName,(Ptr) newNBPType, (Ptr)"\p*");
  291.                 err = PRegisterName(&pb, false);
  292.  
  293.                 if (err != nbpDuplicate) break;
  294.                     /* We registered the name, (or badness happened), so we are done. */
  295.  
  296.                 len = 31;        /* The name we tried already exists, so make up an alternate. */
  297.                 if (++num > 9)
  298.                     --len;
  299.                 if (origLen > len)
  300.                     origLen = len;
  301.                 machineName[0] = origLen;
  302.                 pcatdec(machineName, num);
  303.             }
  304.         }
  305.     }
  306.  
  307.     pb.SETSELF.newSelfFlag = keepSelfFlag;
  308.     PSetSelfSend(&pb, false);
  309.  
  310.     return(err);
  311. }
  312.  
  313.  
  314.  
  315.  
  316. /*****************************************************************************/
  317.  
  318.  
  319.  
  320. /* This function removes the entity specified by theEntity from the registered
  321. ** names queue.  You'll get an error if theEntity hasn't been registered on
  322. ** this Macintosh with RegisterName. */
  323.  
  324. #pragma segment myPPC
  325. OSErr    RemoveNBPAlias(EntityPtr theEntity)
  326. {
  327.     MPPParamBlock    pb;
  328.  
  329.     pb.MPPioCompletion = nil;
  330.     pb.NBPentityPtr    = (Ptr)theEntity;
  331.     return(PRemoveName(&pb, false));
  332. }
  333.  
  334.  
  335.  
  336.